import datetime
import os
import time

from paramiko import SSHClient, AutoAddPolicy


class RemoteFileManager:
    def __init__(self, host, username, password):
        self.host = host
        self.username = username
        self.password = password
        self.client = SSHClient()
        self.client.set_missing_host_key_policy(AutoAddPolicy())

    def connect(self):
        """
        建立SSH连接。
        """
        self.client.connect(self.host, username=self.username, password=self.password)

    def disconnect(self):
        """
        断开SSH连接。
        """
        self.client.close()

    def upload_file(self, local_path, remote_path):
        """
        上传本地文件到远程服务器指定路径。

        Args:
            local_path (str): 本地文件路径。
            remote_path (str): 远程服务器上的目标路径。
        """
        print("upload_file %s %s " % (local_path, remote_path))
        sftp = self.client.open_sftp()
        sftp.put(local_path, remote_path)
        sftp.close()

    def unzip_remote_file(self, remote_zip_path, remote_extract_dir):
        """
        在远程服务器上解压缩指定的ZIP文件到指定目录。

        Args:
            remote_zip_path (str): 远程服务器上的ZIP文件路径。
            remote_extract_dir (str): 解压缩的目标目录。
        """
        _, stdout, stderr = self.client.exec_command(f'unzip -o {remote_zip_path} -d {remote_extract_dir}')
        if stderr.read():
            raise Exception(f"Error unzipping file: {stderr.read().decode('utf-8')}")

    def backup_file(self, remote_source_path, remote_backup_dir, backup_name=None):
        """
        备份远程服务器上的指定文件到指定备份目录。

        Args:
            remote_source_path (str): 需要备份的远程文件路径。
            remote_backup_dir (str): 备份文件存放的远程目录。
            backup_name (str, optional): 备份文件的名称（包括扩展名）。如果不提供，则使用源文件名加上时间戳作为备份文件名。
        """
        if not backup_name:
            backup_name = f"{os.path.basename(remote_source_path)}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
        backup_path = os.path.join(remote_backup_dir, backup_name)

        sftp = self.client.open_sftp()
        sftp.copy(remote_source_path, backup_path)
        sftp.close()
        return backup_path

    def get_remote_dir(self, remote_dir_path):
        """
        获取远程目录下所有子目录的名称。
        Args:
            remote_dir_path (str): 远程服务器上待查询的目录路径。
        Returns:
            list[str]: 子目录名称列表。
        """
        try:
            # 列出远程目录及其属性
            dir_contents = self.client.open_sftp().listdir_attr(remote_dir_path)
            # 筛选出子目录（类型为目录）
            subdirectories = [item.filename for item in dir_contents if item.st_mode & 0o040000 == 0o040000]
            return subdirectories
        except IOError as e:
            print(f"Error accessing remote directory '{remote_dir_path}': {e}")
            return []

    def execute(self, commands):

        """
        执行一系列SSH命令。

        Args:
            commands (list[str]): 要执行的命令列表。
        """
        for cmd in commands:
            print("execute 执行命令： %s" % cmd)
            _, stdout, stderr = self.client.exec_command(cmd)
            print(f"Command Output:\n{stdout.read().decode('utf-8')}")
            if stderr.read():
                print(f"Error: {stderr.read().decode('utf-8')}")


# 需要根据情况进行修改的配置信息。
root_dir = '/home/appyw'
local_file = 'F:\V53\MKPaaS-app'
# 不变的配置信息
server_dir = root_dir + '/server'
formatted_date = datetime.datetime.now().strftime("%Y-%m-%d_%H_%M_%S")
run_jar = ['discovery-center', 'base-server', 'aip-server', 'app-server',
           'bpm-server', 'convert-server', 'gateway-server', 'monitor-server', 'project-base-server']

print("\n请输入操作选项:")
print("1. 备份现有文件")
print("2. 上传文件")
print("3. 解压缩文件")
print("4. 修改配置文件")
print("5. 启动系统")
print("其他退出")
barckup_dir = ''
while True:
    manager = RemoteFileManager('172.19.65.154', 'root', '123456')
    manager.connect()

    if barckup_dir == '':
        barckup_dir = input("\n请输入备份目录：")

    choice = input("输入选项项目(1-5): ")
    if choice == '1':
        backup_dir = 'mv %s  %s/%s' % (server_dir, root_dir, barckup_dir)
        manager.execute([backup_dir])
        manager.disconnect()
    elif choice == '2':
        manager.execute(['mkdir %s' % server_dir])
        for root, dirs, files in os.walk(local_file):
            for file in files:
                manager.upload_file(os.path.join(root, file), server_dir + '/' + file)
        manager.disconnect()
    elif choice == '3':
        manager.execute(['cd %s &&  %s ' % (server_dir, 'for tag in *-*.tar.gz; do tar -xf $tag; done')])
        manager.disconnect()
    elif choice == '4':
        for jar_name in run_jar:
            # cd /root/server && \cp -rf  ../2024-04-24/app-server/config  /root/server/app-server/
            manager.execute([' cd %s && \cp -rf  ../%s/%s/config  %s/%s/' % (
                server_dir, barckup_dir, jar_name, server_dir, jar_name)])
        manager.disconnect()
    elif choice == '5':
        for jar_name in run_jar:
            manager.execute(['cd %s/%s/bin/ && sh run.sh ' % (server_dir, jar_name)])
            if jar_name == 'discovery-center':
                # 启动网关时间长些其他都无所谓
                time.sleep(60)
            else:
                time.sleep(1)
        manager.disconnect()
    else:
        print("退出程序")
        break

# if __name__ == "__main__":
#     manager = RemoteFileManager('172.19.65.154', 'root', '123456')
#     manager.connect()
#
#     barckup_dir = input("请输入备份目录：")
#     # # 第一步：备份现有文件
#     # backup_dir = 'mv %s  %s/%s' % (server_dir, root_dir, barckup_dir)
#     # manager.execute([backup_dir])
#     # #
#     # # # 第二步：上传文件
#     # manager.execute(['mkdir %s' % server_dir])
#     # # # 遍历文件夹
#     # for root, dirs, files in os.walk(local_file):
#     #     for file in files:
#     #         manager.upload_file(os.path.join(root, file), server_dir + '/' + file)
#     #
#     # # # 第三步：解压缩文件
#     # manager.execute(['cd %s &&  %s ' % (server_dir, 'for tag in *-*.tar.gz; do tar -xf $tag; done')])
#
#     # 第四步：修改启动文件的配置信息
#     for jar_name in run_jar:
#         # cd /root/server && \cp -rf  ../2024-04-24/app-server/config  /root/server/app-server/
#         """
#         修改配置文件
#         """
#         manager.execute(
#             [' cd %s && \cp -rf  ../%s/%s/config  %s/%s/' % (server_dir, barckup_dir, jar_name, server_dir, jar_name)])
#
#         """
#             启动服务
#             """
#         manager.execute(['cd %s &&  sh run.sh' % (root_dir + "/" + jar_name + '/bin')])
#         if jar_name == 'discovery-center':
#             # 启动网关时间长些其他都无所谓
#             time.sleep(60)
#         else:
#             time.sleep(1)
#
#     manager.disconnect()
